Prepare county level data

Overview of time windows

US prevalence: 01/21 - 05/18 US socdist: 03/01 - 05/03

UK prevalence: 03/09 - 04/10 UK socdist: 03/01 - 03/31

GER prevalence: 01/01 - 04/25 GER socdist: 02/25 - 04/27

Read and format personality data


df_us_pers <- read_csv('timeseries_usa_county_march1_april_09.csv')

df_us_pers <- df_us_pers %>% select(countyfips, open, sci, extra, agree, stabil) %>% 
  mutate(stabil = -stabil) %>%
  dplyr::rename(county_fips = countyfips,
         pers_o = open, 
         pers_c = sci,
         pers_e = extra,
         pers_a = agree,
         pers_n = stabil) %>% 
  distinct()

Read and format prevalence data


# read data
df_us_covid <- read_csv('USA_timeseries_prep_2005.csv')

# select and renamve variables 
df_us_covid <- df_us_covid %>% 
  select(fips, date, rate) %>% 
  mutate(date = as.Date(date, "%d%b%Y")) %>% 
  rename(county_fips = fips, 
         rate_day = rate)

df_us_covid
NA

Read and format county level controls


df_us_ctrl <- read.csv('controls_US.csv')

df_us_ctrl <- df_us_ctrl %>% select(-county_name) %>% 
  rename(county_fips = county)

df_us_ctrl
NA

Social distancing data unacast


# read data
df_us_socdist <- read_csv('0409_sds-full-county.csv')

df_us_socdist

Social distancing data FB


fb_files <- list.files('../FB Data/US individual files/Mobility/',
                       '*.csv', full.names = T)

df_us_socdist_fb <- fb_files %>% 
  map(read_csv) %>% bind_rows()

df_us_socdist_fb <- df_us_socdist_fb %>%
  select(-age_bracket, -gender, -baseline_name, -baseline_type) %>%
  rename(date = ds,
         county_fips = polygon_id,
         county_name = polygon_name,
         socdist_tiles = all_day_bing_tiles_visited_relative_change,
         socdist_single_tile = all_day_ratio_single_tile_users)

df_us_socdist_fb
NA

Sanity check socdist data


socdist <- df_us_socdist %>% merge(df_us_socdist_fb, by = c("county_fips", "date")) 

socdist[c('daily_distance_diff', 'daily_visitation_diff', 'socdist_tiles', 'socdist_single_tile')] %>% 
  cor(use = 'pairwise.complete')
                      daily_distance_diff daily_visitation_diff socdist_tiles socdist_single_tile
daily_distance_diff             1.0000000             0.1911424     0.3528837          -0.3157188
daily_visitation_diff           0.1911424             1.0000000     0.3964342          -0.3521691
socdist_tiles                   0.3528837             0.3964342     1.0000000          -0.7583523
socdist_single_tile            -0.3157188            -0.3521691    -0.7583523           1.0000000

Merge data


# join data frames 
df_us <- plyr::join_all(list(df_us_covid, df_us_socdist_fb),
                  by = c('county_fips', 'date'), 
                  type = 'inner') %>% 
  plyr::join(df_us_ctrl, by='county_fips') %>% 
  plyr::join(df_us_pers, by='county_fips') %>% 
  arrange(county_fips, date)

# keep only counties with full data
fips_complete <- df_us %>% 
  group_by(county_fips) %>% 
  summarize(n = n()) %>% 
  filter(n==max(.$n)) %>% 
  .$county_fips

df_us <- df_us %>% filter(county_fips %in% fips_complete)

# create sequence of dates
date_sequence <- seq.Date(min(df_us$date),
                          max(df_us$date), 1)
                     
# create data frame with time sequence
df_dates = tibble(date_sequence, 1:length(date_sequence)) 
names(df_dates) <- c('date', 'time')

# merge day index with gps data
df_us = df_us %>% 
  merge(df_dates, by='date') %>% 
  arrange(county_fips) %>%
  as_tibble()

df_us
NA

Explore data

Plot distributions


# distributions of mean prevalence rates per county
df_us %>% group_by(county_fips) %>% 
  summarise(rate_day = mean(rate_day)) %>%
  ggplot(aes(x=rate_day)) + 
  geom_histogram(color="black", fill="white", binwidth = 0.01) +
  ggtitle('Distribution of mean prevalence rates by county')


# distribution of mean sd visit measue
df_us %>% group_by(county_fips) %>% 
  summarise(socdist_single_tile = mean(socdist_single_tile)) %>%
  ggplot(aes(x=socdist_single_tile)) + 
  geom_histogram(color="black", fill="white", bins = 200) +
  ggtitle('Distribution of mean single tile measute by county')

NA
NA

Plot prevalence over time


df_us %>% sample_n(20000) %>%
  ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall prevalence over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% 
  mutate(prev_tail = cut(.[[i]], 
                         breaks = c(-Inf, quantile(.[[i]], 0.05, na.rm=T), 
                                    quantile(.[[i]], 0.95, na.rm=T), Inf),
                         labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(prev_tail != 'center') %>%
  ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~prev_tail) + 
  theme(legend.position="none") + 
  ggtitle(i)

print(gg)
}

Plot social distancing single tile visited


df_us %>% sample_n(10000) %>%
  ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% 
  mutate(dist_tail = cut(.[[i]], 
                         breaks = c(-Inf, quantile(.[[i]], 0.05, na.rm=T), 
                                    quantile(.[[i]], 0.95, na.rm=T), Inf),
                         labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(dist_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~dist_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Control for weekend effect


df_us_loess <- df_us %>% 
  mutate(weekday = format(date, '%u')) %>% 
  filter(!weekday %in% c('6','7')) %>% 
  split(.$county_fips) %>%
  map(~ loess(socdist_single_tile ~ time, data = .)) %>%
  map(predict, 1:max(df_us$time)) %>% 
  bind_rows() %>% 
  gather(key = 'county_fips', value = 'loess') %>% 
  group_by(county_fips) %>% 
  mutate(time = row_number())

df_us <- df_us %>% merge(df_us_loess, by=c('county_fips', 'time')) %>% 
  mutate(weekday = format(date, '%u')) %>% 
  mutate(socdist_single_tile_clean = ifelse(weekday %in% c('6','7'), loess,
                                            socdist_single_tile)) %>%
  arrange(county_fips, time) %>% 
  select(-weekday)

df_us <- df_us %>% drop_na() %>% mutate(time = time-1)

df_us %>% sample_n(10000) %>%
  ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% 
  mutate(dist_tail = cut(.[[i]], 
                         breaks = c(-Inf, quantile(.[[i]], 0.05, na.rm = T), 
                                    quantile(.[[i]], 0.95, na.rm = T), Inf),
                         labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(dist_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=county_name, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~dist_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Variance over time


df_us %>% group_by(time) %>% 
  summarize(socdist_var = var(socdist_single_tile)) %>% 
  ggplot(aes(x=time, y=socdist_var)) +
  geom_line() +
  ggtitle("Variance of social distancing index over time")



df_us %>% group_by(time) %>% 
  summarize(socdist_var = var(socdist_single_tile),
            socdist_var_clean = var(socdist_single_tile_clean)) %>% 
  ggplot() +
  #geom_line(aes(x=time, y=socdist_var)) +
  geom_line(aes(x=time, y=socdist_var_clean)) +
  ggtitle("Variance of smothed social distancing index over time")

Correlations


df_us %>% select(-time, -date, -county_name) %>% 
  group_by(county_fips) %>%
  summarize_if(is.numeric, mean) %>% 
  select(-county_fips) %>%
  cor(use='pairwise.complete.obs') %>% 
  round(3)
                          rate_day socdist_tiles socdist_single_tile airport_distance republican medage
rate_day                     1.000        -0.267               0.163           -0.104     -0.231 -0.106
socdist_tiles               -0.267         1.000              -0.632            0.265      0.393  0.038
socdist_single_tile          0.163        -0.632               1.000           -0.158     -0.293  0.266
airport_distance            -0.104         0.265              -0.158            1.000      0.117  0.019
republican                  -0.231         0.393              -0.293            0.117      1.000  0.135
medage                      -0.106         0.038               0.266            0.019      0.135  1.000
male                        -0.074         0.123              -0.060            0.186      0.161 -0.051
popdens                      0.293        -0.397               0.307           -0.229     -0.370 -0.172
manufact                    -0.065         0.172              -0.190           -0.129      0.164  0.098
tourism                      0.008        -0.120               0.137            0.081     -0.200 -0.090
academics                    0.179        -0.514               0.364           -0.137     -0.451 -0.216
medinc                       0.191        -0.503               0.314           -0.183     -0.193 -0.103
physician_pc                -0.037         0.191              -0.153           -0.034      0.199  0.080
pers_o                       0.124        -0.348               0.281           -0.084     -0.340 -0.036
pers_c                       0.041         0.130              -0.229           -0.092     -0.043 -0.055
pers_e                       0.049        -0.079              -0.036           -0.124     -0.080 -0.098
pers_a                       0.072         0.103              -0.257           -0.100     -0.086 -0.072
pers_n                      -0.120         0.133               0.126            0.049      0.308  0.247
loess                        0.175        -0.636               0.997           -0.170     -0.310  0.263
socdist_single_tile_clean    0.173        -0.633               0.997           -0.170     -0.309  0.265
                            male popdens manufact tourism academics medinc physician_pc pers_o pers_c
rate_day                  -0.074   0.293   -0.065   0.008     0.179  0.191       -0.037  0.124  0.041
socdist_tiles              0.123  -0.397    0.172  -0.120    -0.514 -0.503        0.191 -0.348  0.130
socdist_single_tile       -0.060   0.307   -0.190   0.137     0.364  0.314       -0.153  0.281 -0.229
airport_distance           0.186  -0.229   -0.129   0.081    -0.137 -0.183       -0.034 -0.084 -0.092
republican                 0.161  -0.370    0.164  -0.200    -0.451 -0.193        0.199 -0.340 -0.043
medage                    -0.051  -0.172    0.098  -0.090    -0.216 -0.103        0.080 -0.036 -0.055
male                       1.000  -0.132   -0.073  -0.058    -0.177  0.000        0.172 -0.111 -0.096
popdens                   -0.132   1.000   -0.163   0.096     0.395  0.281       -0.137  0.303 -0.041
manufact                  -0.073  -0.163    1.000  -0.380    -0.387 -0.177        0.157 -0.391  0.067
tourism                   -0.058   0.096   -0.380   1.000     0.275 -0.041       -0.227  0.363  0.010
academics                 -0.177   0.395   -0.387   0.275     1.000  0.721       -0.367  0.458 -0.126
medinc                     0.000   0.281   -0.177  -0.041     0.721  1.000       -0.196  0.223 -0.179
physician_pc               0.172  -0.137    0.157  -0.227    -0.367 -0.196        1.000 -0.214  0.111
pers_o                    -0.111   0.303   -0.391   0.363     0.458  0.223       -0.214  1.000 -0.056
pers_c                    -0.096  -0.041    0.067   0.010    -0.126 -0.179        0.111 -0.056  1.000
pers_e                    -0.068   0.071    0.029  -0.001     0.147  0.140       -0.049 -0.086  0.155
pers_a                    -0.170  -0.054    0.117  -0.072    -0.149 -0.222        0.115 -0.162  0.654
pers_n                     0.065  -0.126    0.183  -0.177    -0.340 -0.215        0.112 -0.226 -0.405
loess                     -0.065   0.317   -0.200   0.154     0.367  0.306       -0.151  0.296 -0.216
socdist_single_tile_clean -0.064   0.316   -0.200   0.153     0.364  0.302       -0.149  0.295 -0.215
                          pers_e pers_a pers_n  loess socdist_single_tile_clean
rate_day                   0.049  0.072 -0.120  0.175                     0.173
socdist_tiles             -0.079  0.103  0.133 -0.636                    -0.633
socdist_single_tile       -0.036 -0.257  0.126  0.997                     0.997
airport_distance          -0.124 -0.100  0.049 -0.170                    -0.170
republican                -0.080 -0.086  0.308 -0.310                    -0.309
medage                    -0.098 -0.072  0.247  0.263                     0.265
male                      -0.068 -0.170  0.065 -0.065                    -0.064
popdens                    0.071 -0.054 -0.126  0.317                     0.316
manufact                   0.029  0.117  0.183 -0.200                    -0.200
tourism                   -0.001 -0.072 -0.177  0.154                     0.153
academics                  0.147 -0.149 -0.340  0.367                     0.364
medinc                     0.140 -0.222 -0.215  0.306                     0.302
physician_pc              -0.049  0.115  0.112 -0.151                    -0.149
pers_o                    -0.086 -0.162 -0.226  0.296                     0.295
pers_c                     0.155  0.654 -0.405 -0.216                    -0.215
pers_e                     1.000  0.244 -0.396 -0.038                    -0.039
pers_a                     0.244  1.000 -0.393 -0.243                    -0.242
pers_n                    -0.396 -0.393  1.000  0.120                     0.122
loess                     -0.038 -0.243  0.120  1.000                     1.000
socdist_single_tile_clean -0.039 -0.242  0.122  1.000                     1.000
  

Model building

Prepare functions


# function calculates all relevant models
run_models <- function(y, lvl1_x, lvl2_x, lvl2_id, data, ctrls=F){

  # subset data
  data = data %>% 
    dplyr::select(all_of(y), all_of(lvl1_x), all_of(lvl2_x), all_of(lvl2_id), 
                  popdens, rate_day, all_of(y))
  data = data %>% 
    dplyr::rename(y = all_of(y),
           lvl1_x = all_of(lvl1_x),
           lvl2_x = all_of(lvl2_x),
           lvl2_id = all_of(lvl2_id)
           )
  
  # configure optimization procedure
  ctrl_config <- lmeControl(opt = 'optim', maxIter = 100, msMaxIter = 100)

  # baseline
  baseline <- lme(fixed = y ~ 1, random = ~ 1 | lvl2_id, 
                    data = data,
                    correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept fixed slope
  random_intercept <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                          random = ~ 1 | lvl2_id,
                            data = data,
                            correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept random slope
  random_slope <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                      random = ~ lvl1_x | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction <- lme(fixed = y ~ lvl1_x * lvl2_x, 
                     random = ~ lvl1_x | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction)
  
  
  if (ctrls == 'dem' | ctrls == 'prev'){
    
    # random intercept random slope
    random_slope_ctrl_dem <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens,
                              random = ~ lvl1_x | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_main_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_int_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')        
    
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem)
  }
  
  if (ctrls == 'prev'){
  
    # random intercept random slope
    random_slope_ctrl_prev <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens + rate_day,
                              random = ~ lvl1_x + rate_day | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')  
    
        # cross level interaction
    interaction_ctrl_main_prev <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens + rate_day,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
  
    # cross level interaction
    interaction_ctrl_int_prev<- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens + rate_day,
                             random = ~ lvl1_x + rate_day | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')
  
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem,                    
                    "random_slope_ctrl_prev" = random_slope_ctrl_prev,
                    "interaction_ctrl_main_prev" = interaction_ctrl_main_prev,
                    "interaction_ctrl_int_prev" = interaction_ctrl_int_prev)
  }
  
  if(ctrls == 'exp'){
    # random intercept random slope
  random_slope_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) + lvl2_x, 
                      random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) * lvl2_x, 
                     random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')  
  
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction,                  
                  "random_slope_exp" = random_slope_exp,
                  "interaction_exp" = interaction_exp)
  }
  
  return(results)
        
}

# extracts table with coefficients and tests statistics
extract_results <- function(models) {
  
  models_summary <- models %>% 
  map(summary) %>% 
  map("tTable") %>% 
  map(as.data.frame) %>% 
  map(round, 10) 
  # %>% map(~ .[str_detect(rownames(.), 'Inter|lvl'),])
  
  return(models_summary)
  
}


compare_models <- function(models) {

  mdl_names <- models %>% names()
  
  str = ''
  for (i in mdl_names){
    
    mdl_str <- paste('models$', i, sep = '')
    
    if(i == 'baseline'){
      str <- mdl_str
    }else{
    str <- paste(str, mdl_str, sep=', ')
    }
  }
  
  anova_str <- paste0('anova(', str, ')')
  mdl_comp <- eval(parse(text=anova_str))
  rownames(mdl_comp) = mdl_names
  return(mdl_comp)
}

Rescale Data


lvl2_scaled <- df_us %>% 
  select(-time, -date, -county_name, -rate_day,
         -socdist_tiles, -socdist_single_tile, -socdist_single_tile_clean, -loess) %>% 
  distinct() %>% 
  mutate_at(vars(-county_fips), scale)

lvl1_scaled <- df_us %>% 
  select(county_fips, time, rate_day, socdist_single_tile, socdist_single_tile_clean) %>% 
  mutate_at(vars(-county_fips, -time), scale)


df_us_scaled <- plyr::join(lvl1_scaled, lvl2_scaled, by = 'county_fips') 
df_us_scaled_prev <- df_us_scaled %>% filter(time > 20 & time <= 50)
df_us_scaled_socdist <- df_us_scaled %>% filter(time <= 30)

Predict prevalence

prevalence ~ openness


models_o_covid <-run_models(y = 'rate_day',
                         lvl1_x = 'time',
                         lvl2_x = 'pers_o',
                         lvl2_id = 'county_fips',
                         data = df_us_scaled_prev,
                         ctrls = 'dem')

extract_results(models_o_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_o_covid)
NA

prevalence ~ conscientiousness


models_c_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_prev,
                         ctrls = 'dem')

extract_results(models_c_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_c_covid)
NA
NA

prevalence ~ extraversion


models_e_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_prev,
                         ctrls = 'dem')

extract_results(models_e_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_e_covid)
NA
NA

prevalence ~ agreeableness


models_a_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_prev,
                         ctrls = 'dem')

extract_results(models_a_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_a_covid)
NA
NA

prevalence ~ neuroticism


models_n_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_prev,
                         ctrls = 'dem')

extract_results(models_n_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_n_covid)
NA
NA

Predict social distancing

social distancing ~ openness


models_o_sd <-run_models(y = 'socdist_single_tile_clean', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_o', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_socdist,
                         ctrls = 'prev')

extract_results(models_o_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_o_sd)
NA
NA

social distancing ~ conscientiousness


models_c_sd <-run_models(y = 'socdist_single_tile_clean', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_socdist,
                         ctrls = 'prev')

extract_results(models_c_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_c_sd)
NA
NA

social distancing ~ extraversion


models_e_sd <-run_models(y = 'socdist_single_tile_clean', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_socdist,
                         ctrls = 'prev')

extract_results(models_e_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_e_sd)
NA
NA

social distancing ~ agreeableness


models_a_sd <-run_models(y = 'socdist_single_tile_clean', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_socdist,
                         ctrls = 'prev')

extract_results(models_a_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_a_sd)
NA
NA

social distancing ~ neuroticism


models_n_sd <-run_models(y = 'socdist_single_tile_clean', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled_socdist,
                         ctrls = 'prev')

extract_results(models_n_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_n_sd)
NA

Create overview table

Define function to create overview tables


summary_table <- function(models, dv_name, prev=F){

  temp_df_ctrl_main <- NULL
  temp_df_ctrl_int <- NULL
  temp_df_ctrl_int_prev <- NULL
  
  for (i in models){
    results <- i %>% extract_results()
    
    results_ctrl_main <- results$interaction_ctrl_main_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_main <- temp_df_ctrl_main %>% rbind(results_ctrl_main)
    
    results_ctrl_int <- results$interaction_ctrl_int_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_int <- temp_df_ctrl_int %>% rbind(results_ctrl_int)
    
    if(prev){
      results_ctrl_int_prev <- results$interaction_ctrl_int_prev['lvl1_x:lvl2_x',]
      temp_df_ctrl_int_prev <- temp_df_ctrl_int_prev %>% rbind(results_ctrl_int_prev)
    }
        
  }
  
  names_ctrl_main <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens')
  rownames(temp_df_ctrl_main) <- names_ctrl_main

  names_ctrl_int <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time')
  rownames(temp_df_ctrl_int) <- names_ctrl_int

  if(prev){
    names_ctrl_int_prev <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time_prev')
    rownames(temp_df_ctrl_int_prev) <- names_ctrl_int_prev
    
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int, temp_df_ctrl_int_prev) %>% round(4)
  }else{
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int) %>% round(4)
  }


  
  return(sum_tab)

} 

Create overview tables

Conditional random forest analysis

Extract slopes


# slope prevalence
df_us_slope_prev <- df_us_scaled_prev %>% split(.$county) %>% 
  map(~ lm(rate_day ~ time, data = .)) %>%
  map(coef) %>% 
  map_dbl('time') %>% 
  as.data.frame() %>% 
  rownames_to_column('county_fips') %>% 
  rename(slope_prev = '.')

df_us_slope_prev <- df_us_scaled_prev %>% 
  select(-time, -rate_day, -socdist_single_tile, -socdist_single_tile_clean) %>%
  distinct() %>% 
  mutate(county_fips = as.character(county_fips)) %>%
  inner_join(df_us_slope_prev, by = 'county_fips') %>%
  drop_na()


# slope social distancing
df_us_slope_socdist <- df_us_scaled_socdist %>% split(.$county) %>% 
  map(~ lm(socdist_single_tile_clean ~ time, data = .)) %>%
  map(coef) %>% 
  map_dbl('time') %>% 
  as.data.frame() %>% 
  rownames_to_column('county_fips') %>% 
  rename(slope_socdist = '.')

df_us_slope_socdist <- df_us_scaled_socdist %>% 
  select(-time, -rate_day, -socdist_single_tile, -socdist_single_tile_clean) %>%
  distinct() %>% 
  mutate(county_fips = as.character(county_fips)) %>%
  inner_join(df_us_slope_socdist, by = 'county_fips') %>%
  drop_na()

Explore distribution of slopes

df_us_slope_prev %>% ggplot(aes(slope_prev)) + geom_histogram(bins = 100)


df_us_slope_socdist %>% ggplot(aes(slope_socdist)) + geom_histogram(bins = 100)

CRF prevalence

CRF prevalence ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_prev <- cforest(slope_prev ~ pers_o + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_o_varimp_prev <- varimp(crf_o_fit_prev, nperm = 1)
crf_o_varimp_cond_prev <- varimp(crf_o_fit_prev, conditional = T, nperm = 1)

crf_o_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') +
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_prev <- cforest(slope_prev ~ pers_c + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_c_varimp_prev <- varimp(crf_c_fit_prev, nperm = 1)
crf_c_varimp_cond_prev <- varimp(crf_c_fit_prev, conditional = T, nperm = 1)

crf_c_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_prev <- cforest(slope_prev ~ pers_e + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_e_varimp_prev <- varimp(crf_e_fit_prev, nperm = 1)
crf_e_varimp_cond_prev <- varimp(crf_e_fit_prev, conditional = T, nperm = 1)

crf_e_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_prev <- cforest(slope_prev ~ pers_a + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_a_varimp_prev <- varimp(crf_a_fit_prev, nperm = 1)
crf_a_varimp_cond_prev <- varimp(crf_a_fit_prev, conditional = T, nperm = 1)

crf_a_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_prev <- cforest(slope_prev ~ pers_n + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_n_varimp_prev <- varimp(crf_n_fit_prev, nperm = 1)
crf_n_varimp_cond_prev <- varimp(crf_n_fit_prev, conditional = T, nperm = 1)

crf_n_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_socdist <- cforest(slope_socdist ~ pers_o + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_o_varimp_socdist <- varimp(crf_o_fit_socdist, nperm = 1)
crf_o_varimp_cond_socdist <- varimp(crf_o_fit_socdist, conditional = T, nperm = 1)

crf_o_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_socdist <- cforest(slope_socdist ~ pers_c + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_c_varimp_socdist <- varimp(crf_c_fit_socdist, nperm = 1)
crf_c_varimp_cond_socdist <- varimp(crf_c_fit_socdist, conditional = T, nperm = 1)

crf_c_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_socdist <- cforest(slope_socdist ~ pers_e + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_e_varimp_socdist <- varimp(crf_e_fit_socdist, nperm = 1)
crf_e_varimp_cond_socdist <- varimp(crf_e_fit_socdist, conditional = T, nperm = 1)

crf_e_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_socdist <- cforest(slope_socdist ~ pers_a + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_a_varimp_socdist <- varimp(crf_a_fit_socdist, nperm = 1)
crf_a_varimp_cond_socdist <- varimp(crf_a_fit_socdist, conditional = T, nperm = 1)

crf_a_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_socdist <- cforest(slope_socdist ~ pers_n + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_n_varimp_socdist <- varimp(crf_n_fit_socdist, nperm = 1)
crf_n_varimp_cond_socdist <- varimp(crf_n_fit_socdist, conditional = T, nperm = 1)

crf_n_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

Predict slopes with linear models

Linear models predicting slopes from personality


lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                         data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()

Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_slope_prev)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.04976 -0.01856 -0.01099  0.00061  0.65628 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.0238571  0.0009781  24.391  < 2e-16 ***
pers_o       0.0062216  0.0010623   5.857 5.38e-09 ***
pers_c      -0.0014123  0.0013288  -1.063  0.28799    
pers_e       0.0007142  0.0010922   0.654  0.51325    
pers_a       0.0046956  0.0013572   3.460  0.00055 ***
pers_n      -0.0027589  0.0012396  -2.226  0.02613 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04746 on 2348 degrees of freedom
Multiple R-squared:  0.03048,   Adjusted R-squared:  0.02841 
F-statistic: 14.76 on 5 and 2348 DF,  p-value: 2.785e-14
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                            data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()

Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_slope_socdist)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.087141 -0.017732 -0.002132  0.015939  0.117901 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.0890251  0.0005317 167.419  < 2e-16 ***
pers_o       0.0098530  0.0005775  17.061  < 2e-16 ***
pers_c      -0.0046798  0.0007224  -6.478 1.13e-10 ***
pers_e       0.0036028  0.0005938   6.067 1.51e-09 ***
pers_a      -0.0042767  0.0007378  -5.796 7.69e-09 ***
pers_n      -0.0022425  0.0006739  -3.328 0.000889 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0258 on 2348 degrees of freedom
Multiple R-squared:  0.2149,    Adjusted R-squared:  0.2132 
F-statistic: 128.5 on 5 and 2348 DF,  p-value: < 2.2e-16

Linear models predicting slopes with controls


lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                           airport_distance + republican + medage + male + popdens + 
                           manufact + tourism + academics + medinc + physician_pc,
                         data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()

Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_slope_prev)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.25258 -0.01651 -0.00794  0.00215  0.61997 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)       0.0238571  0.0009252  25.785  < 2e-16 ***
pers_o            0.0018446  0.0011817   1.561  0.11867    
pers_c            0.0003194  0.0012802   0.250  0.80299    
pers_e           -0.0006724  0.0010511  -0.640  0.52246    
pers_a            0.0049324  0.0013486   3.657  0.00026 ***
pers_n            0.0003769  0.0012885   0.293  0.76990    
airport_distance -0.0003157  0.0010100  -0.313  0.75462    
republican       -0.0067393  0.0011283  -5.973 2.69e-09 ***
medage           -0.0023197  0.0009878  -2.348  0.01894 *  
male             -0.0030689  0.0010206  -3.007  0.00267 ** 
popdens           0.0109511  0.0010752  10.185  < 2e-16 ***
manufact         -0.0025844  0.0011141  -2.320  0.02045 *  
tourism          -0.0011665  0.0011061  -1.055  0.29174    
academics        -0.0081414  0.0018624  -4.372 1.29e-05 ***
medinc            0.0100963  0.0015427   6.545 7.30e-11 ***
physician_pc      0.0002815  0.0010233   0.275  0.78329    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04489 on 2338 degrees of freedom
Multiple R-squared:  0.1361,    Adjusted R-squared:  0.1306 
F-statistic: 24.56 on 15 and 2338 DF,  p-value: < 2.2e-16
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                              airport_distance + republican + medage + male + popdens + 
                              manufact + tourism + academics + medinc + physician_pc,
                            data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()

Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_slope_socdist)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.066827 -0.012101 -0.000994  0.011822  0.092012 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)       8.903e-02  3.787e-04 235.069  < 2e-16 ***
pers_o            2.401e-03  4.837e-04   4.965 7.37e-07 ***
pers_c           -1.505e-03  5.240e-04  -2.872  0.00411 ** 
pers_e            1.168e-03  4.303e-04   2.715  0.00667 ** 
pers_a           -1.429e-03  5.520e-04  -2.588  0.00970 ** 
pers_n            4.506e-03  5.274e-04   8.543  < 2e-16 ***
airport_distance -2.103e-03  4.134e-04  -5.087 3.92e-07 ***
republican       -8.400e-03  4.618e-04 -18.188  < 2e-16 ***
medage            2.352e-03  4.043e-04   5.816 6.85e-09 ***
male              5.781e-04  4.178e-04   1.384  0.16655    
popdens           3.372e-03  4.401e-04   7.662 2.67e-14 ***
manufact          1.231e-03  4.560e-04   2.700  0.00699 ** 
tourism           3.117e-03  4.528e-04   6.884 7.43e-12 ***
academics         4.986e-03  7.623e-04   6.541 7.47e-11 ***
medinc            1.148e-02  6.314e-04  18.175  < 2e-16 ***
physician_pc     -3.975e-05  4.189e-04  -0.095  0.92441    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.01837 on 2338 degrees of freedom
Multiple R-squared:  0.6034,    Adjusted R-squared:  0.6009 
F-statistic: 237.2 on 15 and 2338 DF,  p-value: < 2.2e-16

Change point analysis

Preparation


# keep only counties with full data
fips_complete <- df_us_scaled %>% 
  group_by(county_fips) %>% 
  summarize(n = n()) %>% 
  filter(n==max(.$n)) %>% 
  .$county_fips

Prevalence


# run changepoint analysis
df_us_prev_cpt_results <- df_us_scaled %>% select(county_fips, rate_day) %>%
  filter(county_fips %in% fips_complete) %>% 
  split(.$county_fips) %>%
  map(~ cpt.meanvar(as.vector(.$rate_day),
                    class=TRUE,
                    param.estimates=TRUE,
                    Q=1))

# calculate change point
df_us_prev_cpt_day <- df_us_prev_cpt_results %>% 
  map(cpts) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(cpt_day_prev = '.') %>%
  rownames_to_column('county_fips')

# calculate mean differences
df_us_prev_cpt_mean_diff <- df_us_prev_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$mean) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(mean_diff_prev = '.') %>%
  rownames_to_column('county_fips')

# calculate varaince differences
df_us_prev_cpt_var_diff <- df_us_prev_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$variance) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(var_diff_prev = '.') %>%
  rownames_to_column('county_fips')

# merge new variables 
df_us_cpt_prev <- df_us_scaled %>%
  select(-time, -rate_day, -socdist_single_tile, -socdist_single_tile_clean) %>%
  distinct() %>%
  mutate(county_fips = as.character(county_fips)) %>%
  left_join(df_us_prev_cpt_day, by='county_fips') %>%
  left_join(df_us_prev_cpt_mean_diff, by='county_fips') %>%
  left_join(df_us_prev_cpt_var_diff, by='county_fips')

df_us_cpt_prev %>% select(cpt_day_prev) %>% map(hist)
$cpt_day_prev
$breaks
 [1]  5 10 15 20 25 30 35 40 45 50 55 60

$counts
 [1]  72 245 411 706 179 303 177 101  34  29  14

$density
 [1] 0.006340819 0.021576398 0.036195509 0.062175253 0.015763981 0.026684280 0.015587847 0.008894760 0.002994276
[10] 0.002553941 0.001232937

$mids
 [1]  7.5 12.5 17.5 22.5 27.5 32.5 37.5 42.5 47.5 52.5 57.5

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(mean_diff_prev) %>% map(hist)
$mean_diff_prev
$breaks
 [1] -1  0  1  2  3  4  5  6  7  8  9 10 11

$counts
 [1]    3 2056  132   38   11   10    7    5    2    2    4    1

$density
 [1] 0.0013210040 0.9053280493 0.0581241744 0.0167327169 0.0048436812 0.0044033465 0.0030823426 0.0022016733 0.0008806693
[10] 0.0008806693 0.0017613386 0.0004403347

$mids
 [1] -0.5  0.5  1.5  2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5 10.5

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(var_diff_prev) %>% map(hist)
$var_diff_prev
$breaks
 [1] -10   0  10  20  30  40  50  60  70  80  90 100 110 120 130

$counts
 [1]   48 2192   12    8    4    1    1    1    2    0    1    0    0    1

$density
 [1] 2.113606e-03 9.652136e-02 5.284016e-04 3.522677e-04 1.761339e-04 4.403347e-05 4.403347e-05 4.403347e-05 8.806693e-05
[10] 0.000000e+00 4.403347e-05 0.000000e+00 0.000000e+00 4.403347e-05

$mids
 [1]  -5   5  15  25  35  45  55  65  75  85  95 105 115 125

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% dim()
[1] 2354   19
df_us_cpt_prev %>% drop_na() %>% dim()
[1] 2271   19

for(i in head(df_us_prev_cpt_results,18)){
  plot(i)
}

NA

Social distancing


# run changepoint analysis
df_us_socdist_cpt_results <- df_us_scaled %>% select(county_fips, socdist_single_tile_clean) %>%
  filter(county_fips %in% fips_complete) %>% 
  split(.$county_fips) %>%
  map(~ cpt.meanvar(as.vector(.$socdist_single_tile_clean),
                    #penalty = 'Asymptotic',
                    class=TRUE,
                    param.estimates=TRUE,
                    Q=1,
                    test.stat = 'Normal'))

# calculate change point
df_us_socdist_cpt_day <- df_us_socdist_cpt_results %>% 
  map(cpts) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(cpt_day_socdist = '.') %>%
  rownames_to_column('county_fips')

# calculate mean differences
df_us_socdist_cpt_mean_diff <- df_us_socdist_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$mean) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(mean_diff_socdist = '.') %>%
  rownames_to_column('county_fips')

# calculate varaince differences
df_us_socdist_cpt_var_diff <- df_us_socdist_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$variance) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(var_diff_socdist = '.') %>%
  rownames_to_column('county_fips')

# merge new variables 
df_us_cpt_prev_socdist <- df_us_cpt_prev %>%
  left_join(df_us_socdist_cpt_day, by='county_fips') %>%
  left_join(df_us_socdist_cpt_mean_diff, by='county_fips') %>%
  left_join(df_us_socdist_cpt_var_diff, by='county_fips')

df_us_cpt_prev_socdist %>% select(cpt_day_socdist) %>% map(hist)
$cpt_day_socdist
$breaks
 [1]  0  5 10 15 20 25 30 35 40 45 50 55 60

$counts
 [1]    1    2 1124 1136   86    2    1    0    0    0    0    2

$density
 [1] 8.496177e-05 1.699235e-04 9.549703e-02 9.651657e-02 7.306712e-03 1.699235e-04 8.496177e-05 0.000000e+00 0.000000e+00
[10] 0.000000e+00 0.000000e+00 1.699235e-04

$mids
 [1]  2.5  7.5 12.5 17.5 22.5 27.5 32.5 37.5 42.5 47.5 52.5 57.5

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(mean_diff_socdist) %>% map(hist)
$mean_diff_socdist
$breaks
 [1] -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5

$counts
 [1]    1    1    0    0  194 1034  680  292  110   33    8    1

$density
 [1] 0.0008496177 0.0008496177 0.0000000000 0.0000000000 0.1648258284 0.8785046729 0.5777400170 0.2480883602 0.0934579439
[10] 0.0280373832 0.0067969414 0.0008496177

$mids
 [1] -1.25 -0.75 -0.25  0.25  0.75  1.25  1.75  2.25  2.75  3.25  3.75  4.25

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(var_diff_socdist) %>% map(hist)
$var_diff_socdist
$breaks
[1] -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5  2.0  2.5

$counts
[1]    4   32  728 1550   37    0    0    1

$density
[1] 0.0034013605 0.0272108844 0.6190476190 1.3180272109 0.0314625850 0.0000000000 0.0000000000 0.0008503401

$mids
[1] -1.25 -0.75 -0.25  0.25  0.75  1.25  1.75  2.25

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% dim()
[1] 2354   22
df_us_cpt_prev_socdist %>% drop_na() %>% dim()
[1] 2269   22

for(i in head(df_us_socdist_cpt_results,18)){
  plot(i)
}

NA

Predicting change points

Linear models predicting change points (no controls)


lm_cpr_prev_pers <- lm(cpt_day_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                         data = df_us_cpt_prev_socdist)
lm_cpr_prev_pers %>% summary()

Call:
lm(formula = cpt_day_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-25.983  -6.334  -1.311   4.562  45.235 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 25.16757    0.18974 132.643  < 2e-16 ***
pers_o      -3.18568    0.20844 -15.283  < 2e-16 ***
pers_c       0.15689    0.26060   0.602 0.547216    
pers_e      -0.74089    0.21574  -3.434 0.000605 ***
pers_a       0.05043    0.26716   0.189 0.850296    
pers_n       1.71404    0.24456   7.009 3.16e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 9.039 on 2265 degrees of freedom
  (83 observations deleted due to missingness)
Multiple R-squared:  0.165, Adjusted R-squared:  0.1631 
F-statistic: 89.49 on 5 and 2265 DF,  p-value: < 2.2e-16
lm_cpt_socdist_pers <- lm(cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                            data = df_us_cpt_prev_socdist)
lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-12.015  -3.127   0.280   2.588  45.256 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 15.35217    0.06752 227.366  < 2e-16 ***
pers_o       0.27316    0.07333   3.725   0.0002 ***
pers_c       0.12880    0.09174   1.404   0.1604    
pers_e      -0.12366    0.07540  -1.640   0.1011    
pers_a       0.15698    0.09369   1.675   0.0940 .  
pers_n      -0.33375    0.08557  -3.900 9.88e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.276 on 2348 degrees of freedom
Multiple R-squared:  0.02963,   Adjusted R-squared:  0.02756 
F-statistic: 14.34 on 5 and 2348 DF,  p-value: 7.46e-14

Linear models predicting change points with controls


lm_cpt_prev_pers <- lm(cpt_day_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                           airport_distance + republican + medage + male + popdens + 
                           manufact + tourism + academics + medinc + physician_pc,
                         data = df_us_cpt_prev_socdist)
lm_cpt_prev_pers %>% summary()

Call:
lm(formula = cpt_day_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-22.083  -5.327  -1.200   4.136  35.617 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      25.29704    0.16734 151.174  < 2e-16 ***
pers_o           -1.63993    0.21671  -7.568 5.51e-14 ***
pers_c           -0.56105    0.23371  -2.401  0.01645 *  
pers_e           -0.04365    0.19394  -0.225  0.82196    
pers_a           -0.32564    0.24839  -1.311  0.19000    
pers_n            0.04299    0.23672   0.182  0.85590    
airport_distance  1.43258    0.18667   7.674 2.46e-14 ***
republican        1.03176    0.20387   5.061 4.51e-07 ***
medage            1.79449    0.17925  10.011  < 2e-16 ***
male              0.93638    0.18582   5.039 5.05e-07 ***
popdens           0.30541    0.19128   1.597  0.11047    
manufact         -0.10909    0.20215  -0.540  0.58950    
tourism          -0.74632    0.20100  -3.713  0.00021 ***
academics        -1.02735    0.33531  -3.064  0.00221 ** 
medinc           -2.10327    0.27916  -7.534 7.06e-14 ***
physician_pc      0.90426    0.18442   4.903 1.01e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.967 on 2255 degrees of freedom
  (83 observations deleted due to missingness)
Multiple R-squared:  0.3543,    Adjusted R-squared:   0.35 
F-statistic: 82.47 on 15 and 2255 DF,  p-value: < 2.2e-16
lm_cpt_socdist_pers <- lm(cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                              airport_distance + republican + medage + male + popdens + 
                              manufact + tourism + academics + medinc + physician_pc,
                            data = df_us_cpt_prev_socdist)
lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-11.950  -2.950   0.227   2.481  45.278 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)      15.352167   0.066954 229.295  < 2e-16 ***
pers_o            0.191294   0.085515   2.237  0.02538 *  
pers_c            0.079700   0.092637   0.860  0.38969    
pers_e           -0.118342   0.076064  -1.556  0.11988    
pers_a            0.134201   0.097590   1.375  0.16921    
pers_n           -0.377922   0.093244  -4.053 5.22e-05 ***
airport_distance -0.134089   0.073088  -1.835  0.06669 .  
republican       -0.001739   0.081650  -0.021  0.98301    
medage           -0.085162   0.071481  -1.191  0.23362    
male              0.019984   0.073857   0.271  0.78675    
popdens           0.342335   0.077808   4.400 1.13e-05 ***
manufact         -0.249618   0.080622  -3.096  0.00198 ** 
tourism           0.120821   0.080045   1.509  0.13133    
academics        -0.380811   0.134768  -2.826  0.00476 ** 
medinc            0.026925   0.111634   0.241  0.80943    
physician_pc      0.108887   0.074052   1.470  0.14159    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.248 on 2338 degrees of freedom
Multiple R-squared:  0.04995,   Adjusted R-squared:  0.04386 
F-statistic: 8.196 on 15 and 2338 DF,  p-value: < 2.2e-16
LS0tCnRpdGxlOiAiQ09WSUQtMTkgVVMiCmF1dGhvcjogIkhlaW5yaWNoIFBldGVycyIKZGF0ZTogIjQvMTUvMjAyMCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCiMgTUFDCiBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICcvVXNlcnMvaHAyNTAwL0dvb2dsZSBEcml2ZS9TVFVEWS9Db2x1bWJpYS9SZXNlYXJjaC9Db3JvbmEvRGF0YS9VUycpCgpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KG5sbWUpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGFydHkpCmxpYnJhcnkoZG9QYXJhbGxlbCkKbGlicmFyeShjaGFuZ2Vwb2ludCkKCgpgYGAKCgojIFByZXBhcmUgY291bnR5IGxldmVsIGRhdGEgCgojIyMgT3ZlcnZpZXcgb2YgdGltZSB3aW5kb3dzClVTIHByZXZhbGVuY2U6IDAxLzIxIC0gMDUvMTgKVVMgc29jZGlzdDogMDMvMDEgLSAwNS8wMwoKVUsgcHJldmFsZW5jZTogMDMvMDkgLSAwNC8xMApVSyBzb2NkaXN0OiAwMy8wMSAtIDAzLzMxCgpHRVIgcHJldmFsZW5jZTogMDEvMDEgLSAwNC8yNQpHRVIgc29jZGlzdDogMDIvMjUgLSAwNC8yNwoKIyMjIFJlYWQgYW5kIGZvcm1hdCBwZXJzb25hbGl0eSBkYXRhIApgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmRmX3VzX3BlcnMgPC0gcmVhZF9jc3YoJ3RpbWVzZXJpZXNfdXNhX2NvdW50eV9tYXJjaDFfYXByaWxfMDkuY3N2JykKCmRmX3VzX3BlcnMgPC0gZGZfdXNfcGVycyAlPiUgc2VsZWN0KGNvdW50eWZpcHMsIG9wZW4sIHNjaSwgZXh0cmEsIGFncmVlLCBzdGFiaWwpICU+JSAKICBtdXRhdGUoc3RhYmlsID0gLXN0YWJpbCkgJT4lCiAgZHBseXI6OnJlbmFtZShjb3VudHlfZmlwcyA9IGNvdW50eWZpcHMsCiAgICAgICAgIHBlcnNfbyA9IG9wZW4sIAogICAgICAgICBwZXJzX2MgPSBzY2ksCiAgICAgICAgIHBlcnNfZSA9IGV4dHJhLAogICAgICAgICBwZXJzX2EgPSBhZ3JlZSwKICAgICAgICAgcGVyc19uID0gc3RhYmlsKSAlPiUgCiAgZGlzdGluY3QoKQoKYGBgCgojIyMgUmVhZCBhbmQgZm9ybWF0IHByZXZhbGVuY2UgZGF0YSAKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojIHJlYWQgZGF0YQpkZl91c19jb3ZpZCA8LSByZWFkX2NzdignVVNBX3RpbWVzZXJpZXNfcHJlcF8yMDA1LmNzdicpCgojIHNlbGVjdCBhbmQgcmVuYW12ZSB2YXJpYWJsZXMgCmRmX3VzX2NvdmlkIDwtIGRmX3VzX2NvdmlkICU+JSAKICBzZWxlY3QoZmlwcywgZGF0ZSwgcmF0ZSkgJT4lIAogIG11dGF0ZShkYXRlID0gYXMuRGF0ZShkYXRlLCAiJWQlYiVZIikpICU+JSAKICByZW5hbWUoY291bnR5X2ZpcHMgPSBmaXBzLCAKICAgICAgICAgcmF0ZV9kYXkgPSByYXRlKQoKZGZfdXNfY292aWQKCmBgYAoKIyMjIFJlYWQgYW5kIGZvcm1hdCBjb3VudHkgbGV2ZWwgY29udHJvbHMgCmBgYHtyfQoKZGZfdXNfY3RybCA8LSByZWFkLmNzdignY29udHJvbHNfVVMuY3N2JykKCmRmX3VzX2N0cmwgPC0gZGZfdXNfY3RybCAlPiUgc2VsZWN0KC1jb3VudHlfbmFtZSkgJT4lIAogIHJlbmFtZShjb3VudHlfZmlwcyA9IGNvdW50eSkKCmRmX3VzX2N0cmwKCmBgYAoKCiMjIyBTb2NpYWwgZGlzdGFuY2luZyBkYXRhIHVuYWNhc3QKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojIHJlYWQgZGF0YQpkZl91c19zb2NkaXN0IDwtIHJlYWRfY3N2KCcwNDA5X3Nkcy1mdWxsLWNvdW50eS5jc3YnKQoKZGZfdXNfc29jZGlzdApgYGAKCgojIyMgU29jaWFsIGRpc3RhbmNpbmcgZGF0YSBGQgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmZiX2ZpbGVzIDwtIGxpc3QuZmlsZXMoJy4uL0ZCIERhdGEvVVMgaW5kaXZpZHVhbCBmaWxlcy9Nb2JpbGl0eS8nLAogICAgICAgICAgICAgICAgICAgICAgICcqLmNzdicsIGZ1bGwubmFtZXMgPSBUKQoKZGZfdXNfc29jZGlzdF9mYiA8LSBmYl9maWxlcyAlPiUgCiAgbWFwKHJlYWRfY3N2KSAlPiUgYmluZF9yb3dzKCkKCmRmX3VzX3NvY2Rpc3RfZmIgPC0gZGZfdXNfc29jZGlzdF9mYiAlPiUKICBzZWxlY3QoLWFnZV9icmFja2V0LCAtZ2VuZGVyLCAtYmFzZWxpbmVfbmFtZSwgLWJhc2VsaW5lX3R5cGUpICU+JQogIHJlbmFtZShkYXRlID0gZHMsCiAgICAgICAgIGNvdW50eV9maXBzID0gcG9seWdvbl9pZCwKICAgICAgICAgY291bnR5X25hbWUgPSBwb2x5Z29uX25hbWUsCiAgICAgICAgIHNvY2Rpc3RfdGlsZXMgPSBhbGxfZGF5X2JpbmdfdGlsZXNfdmlzaXRlZF9yZWxhdGl2ZV9jaGFuZ2UsCiAgICAgICAgIHNvY2Rpc3Rfc2luZ2xlX3RpbGUgPSBhbGxfZGF5X3JhdGlvX3NpbmdsZV90aWxlX3VzZXJzKQoKZGZfdXNfc29jZGlzdF9mYgoKYGBgCgojIyMgU2FuaXR5IGNoZWNrIHNvY2Rpc3QgZGF0YQpgYGB7cn0KCnNvY2Rpc3QgPC0gZGZfdXNfc29jZGlzdCAlPiUgbWVyZ2UoZGZfdXNfc29jZGlzdF9mYiwgYnkgPSBjKCJjb3VudHlfZmlwcyIsICJkYXRlIikpIAoKc29jZGlzdFtjKCdkYWlseV9kaXN0YW5jZV9kaWZmJywgJ2RhaWx5X3Zpc2l0YXRpb25fZGlmZicsICdzb2NkaXN0X3RpbGVzJywgJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnKV0gJT4lIAogIGNvcih1c2UgPSAncGFpcndpc2UuY29tcGxldGUnKQoKYGBgCgoKIyMjIE1lcmdlIGRhdGEKYGBge3J9CgojIGpvaW4gZGF0YSBmcmFtZXMgCmRmX3VzIDwtIHBseXI6OmpvaW5fYWxsKGxpc3QoZGZfdXNfY292aWQsIGRmX3VzX3NvY2Rpc3RfZmIpLAogICAgICAgICAgICAgICAgICBieSA9IGMoJ2NvdW50eV9maXBzJywgJ2RhdGUnKSwgCiAgICAgICAgICAgICAgICAgIHR5cGUgPSAnaW5uZXInKSAlPiUgCiAgcGx5cjo6am9pbihkZl91c19jdHJsLCBieT0nY291bnR5X2ZpcHMnKSAlPiUgCiAgcGx5cjo6am9pbihkZl91c19wZXJzLCBieT0nY291bnR5X2ZpcHMnKSAlPiUgCiAgYXJyYW5nZShjb3VudHlfZmlwcywgZGF0ZSkKCiMga2VlcCBvbmx5IGNvdW50aWVzIHdpdGggZnVsbCBkYXRhCmZpcHNfY29tcGxldGUgPC0gZGZfdXMgJT4lIAogIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXplKG4gPSBuKCkpICU+JSAKICBmaWx0ZXIobj09bWF4KC4kbikpICU+JSAKICAuJGNvdW50eV9maXBzCgpkZl91cyA8LSBkZl91cyAlPiUgZmlsdGVyKGNvdW50eV9maXBzICVpbiUgZmlwc19jb21wbGV0ZSkKCiMgY3JlYXRlIHNlcXVlbmNlIG9mIGRhdGVzCmRhdGVfc2VxdWVuY2UgPC0gc2VxLkRhdGUobWluKGRmX3VzJGRhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1heChkZl91cyRkYXRlKSwgMSkKICAgICAgICAgICAgICAgICAgICAgCiMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCB0aW1lIHNlcXVlbmNlCmRmX2RhdGVzID0gdGliYmxlKGRhdGVfc2VxdWVuY2UsIDE6bGVuZ3RoKGRhdGVfc2VxdWVuY2UpKSAKbmFtZXMoZGZfZGF0ZXMpIDwtIGMoJ2RhdGUnLCAndGltZScpCgojIG1lcmdlIGRheSBpbmRleCB3aXRoIGdwcyBkYXRhCmRmX3VzID0gZGZfdXMgJT4lIAogIG1lcmdlKGRmX2RhdGVzLCBieT0nZGF0ZScpICU+JSAKICBhcnJhbmdlKGNvdW50eV9maXBzKSAlPiUKICBhc190aWJibGUoKQoKZGZfdXMKCmBgYAoKIyMgRXhwbG9yZSBkYXRhCiMjIyBQbG90IGRpc3RyaWJ1dGlvbnMKYGBge3IsIHdhcm5pbmc9RkFMU0V9CgojIGRpc3RyaWJ1dGlvbnMgb2YgbWVhbiBwcmV2YWxlbmNlIHJhdGVzIHBlciBjb3VudHkKZGZfdXMgJT4lIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXNlKHJhdGVfZGF5ID0gbWVhbihyYXRlX2RheSkpICU+JQogIGdncGxvdChhZXMoeD1yYXRlX2RheSkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsYWNrIiwgZmlsbD0id2hpdGUiLCBiaW53aWR0aCA9IDAuMDEpICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiBwcmV2YWxlbmNlIHJhdGVzIGJ5IGNvdW50eScpCgojIGRpc3RyaWJ1dGlvbiBvZiBtZWFuIHNkIHZpc2l0IG1lYXN1ZQpkZl91cyAlPiUgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBzdW1tYXJpc2Uoc29jZGlzdF9zaW5nbGVfdGlsZSA9IG1lYW4oc29jZGlzdF9zaW5nbGVfdGlsZSkpICU+JQogIGdncGxvdChhZXMoeD1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIsIGJpbnMgPSAyMDApICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiBzaW5nbGUgdGlsZSBtZWFzdXRlIGJ5IGNvdW50eScpCgoKYGBgCgojIyMgUGxvdCBwcmV2YWxlbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigyMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9cmF0ZV9kYXkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1wb3BkZW5zKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiT3ZlcmFsbCBwcmV2YWxlbmNlIG92ZXIgdGltZSIpCgpwZXJzIDwtIGMoJ3BlcnNfbycsICdwZXJzX2MnLCAncGVyc19lJywgJ3BlcnNfYScsICdwZXJzX24nKQoKZm9yIChpIGluIHBlcnMpewoKZ2cgPC0gZGZfdXMgJT4lIAogIG11dGF0ZShwcmV2X3RhaWwgPSBjdXQoLltbaV1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoLUluZiwgcXVhbnRpbGUoLltbaV1dLCAwLjA1LCBuYS5ybT1UKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50aWxlKC5bW2ldXSwgMC45NSwgbmEucm09VCksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKHByZXZfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9cmF0ZV9kYXkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1wb3BkZW5zKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICBmYWNldF93cmFwKH5wcmV2X3RhaWwpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyAKICBnZ3RpdGxlKGkpCgpwcmludChnZykKfQoKYGBgCgojIyMgUGxvdCBzb2NpYWwgZGlzdGFuY2luZyBzaW5nbGUgdGlsZSB2aXNpdGVkCmBgYHtyfQoKZGZfdXMgJT4lIHNhbXBsZV9uKDEwMDAwKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2w9Y291bnR5X25hbWUsIHNpemU9cG9wZGVucykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPVQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoIk92ZXJhbGwgc29jaWFsIGRpc3RhbmNpbmcgKHNpbmdsZSB0aWxlKSBvdmVyIHRpbWUiKQoKcGVycyA8LSBjKCdwZXJzX28nLCAncGVyc19jJywgJ3BlcnNfZScsICdwZXJzX2EnLCAncGVyc19uJykKCmZvciAoaSBpbiBwZXJzKXsKCmdnIDwtIGRmX3VzICU+JSAKICBtdXRhdGUoZGlzdF90YWlsID0gY3V0KC5bW2ldXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4wNSwgbmEucm09VCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudGlsZSguW1tpXV0sIDAuOTUsIG5hLnJtPVQpLCBJbmYpLAogICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygnbG93ZXIgdGFpbCcsICdjZW50ZXInLCAndXBwZXIgdGFpbCcpKSkgJT4lIAogIGZpbHRlcihkaXN0X3RhaWwgIT0gJ2NlbnRlcicpICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1wb3BkZW5zKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICBmYWNldF93cmFwKH5kaXN0X3RhaWwpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoaSkKCnByaW50KGdnKQp9CgpgYGAKCiMjIyBDb250cm9sIGZvciB3ZWVrZW5kIGVmZmVjdCAKYGBge3J9CgpkZl91c19sb2VzcyA8LSBkZl91cyAlPiUgCiAgbXV0YXRlKHdlZWtkYXkgPSBmb3JtYXQoZGF0ZSwgJyV1JykpICU+JSAKICBmaWx0ZXIoIXdlZWtkYXkgJWluJSBjKCc2JywnNycpKSAlPiUgCiAgc3BsaXQoLiRjb3VudHlfZmlwcykgJT4lCiAgbWFwKH4gbG9lc3Moc29jZGlzdF9zaW5nbGVfdGlsZSB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKHByZWRpY3QsIDE6bWF4KGRmX3VzJHRpbWUpKSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lIAogIGdhdGhlcihrZXkgPSAnY291bnR5X2ZpcHMnLCB2YWx1ZSA9ICdsb2VzcycpICU+JSAKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIG11dGF0ZSh0aW1lID0gcm93X251bWJlcigpKQoKZGZfdXMgPC0gZGZfdXMgJT4lIG1lcmdlKGRmX3VzX2xvZXNzLCBieT1jKCdjb3VudHlfZmlwcycsICd0aW1lJykpICU+JSAKICBtdXRhdGUod2Vla2RheSA9IGZvcm1hdChkYXRlLCAnJXUnKSkgJT4lIAogIG11dGF0ZShzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuID0gaWZlbHNlKHdlZWtkYXkgJWluJSBjKCc2JywnNycpLCBsb2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2NkaXN0X3NpbmdsZV90aWxlKSkgJT4lCiAgYXJyYW5nZShjb3VudHlfZmlwcywgdGltZSkgJT4lIAogIHNlbGVjdCgtd2Vla2RheSkKCmRmX3VzIDwtIGRmX3VzICU+JSBkcm9wX25hKCkgJT4lIG11dGF0ZSh0aW1lID0gdGltZS0xKQoKYGBgCgpgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigxMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPXBvcGRlbnMpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJPdmVyYWxsIHNvY2lhbCBkaXN0YW5jaW5nIChzaW5nbGUgdGlsZSkgb3ZlciB0aW1lIikKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl91cyAlPiUgCiAgbXV0YXRlKGRpc3RfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtSW5mLCBxdWFudGlsZSguW1tpXV0sIDAuMDUsIG5hLnJtID0gVCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudGlsZSguW1tpXV0sIDAuOTUsIG5hLnJtID0gVCksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKGRpc3RfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPXBvcGRlbnMpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofmRpc3RfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKIyMjIFZhcmlhbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBncm91cF9ieSh0aW1lKSAlPiUgCiAgc3VtbWFyaXplKHNvY2Rpc3RfdmFyID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF92YXIpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdndGl0bGUoIlZhcmlhbmNlIG9mIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgoKZGZfdXMgJT4lIGdyb3VwX2J5KHRpbWUpICU+JSAKICBzdW1tYXJpemUoc29jZGlzdF92YXIgPSB2YXIoc29jZGlzdF9zaW5nbGVfdGlsZSksCiAgICAgICAgICAgIHNvY2Rpc3RfdmFyX2NsZWFuID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pKSAlPiUgCiAgZ2dwbG90KCkgKwogICNnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3ZhcikpICsKICBnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3Zhcl9jbGVhbikpICsKICBnZ3RpdGxlKCJWYXJpYW5jZSBvZiBzbW90aGVkIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgpgYGAKCgojIyMgQ29ycmVsYXRpb25zIAoKYGBge3J9CgpkZl91cyAlPiUgc2VsZWN0KC10aW1lLCAtZGF0ZSwgLWNvdW50eV9uYW1lKSAlPiUgCiAgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JQogIHN1bW1hcml6ZV9pZihpcy5udW1lcmljLCBtZWFuKSAlPiUgCiAgc2VsZWN0KC1jb3VudHlfZmlwcykgJT4lCiAgY29yKHVzZT0ncGFpcndpc2UuY29tcGxldGUub2JzJykgJT4lIAogIHJvdW5kKDMpCiAgCmBgYAoKCiMgTW9kZWwgYnVpbGRpbmcKCiMjIFByZXBhcmUgZnVuY3Rpb25zCgpgYGB7cn0KCiMgZnVuY3Rpb24gY2FsY3VsYXRlcyBhbGwgcmVsZXZhbnQgbW9kZWxzCnJ1bl9tb2RlbHMgPC0gZnVuY3Rpb24oeSwgbHZsMV94LCBsdmwyX3gsIGx2bDJfaWQsIGRhdGEsIGN0cmxzPUYpewoKICAjIHN1YnNldCBkYXRhCiAgZGF0YSA9IGRhdGEgJT4lIAogICAgZHBseXI6OnNlbGVjdChhbGxfb2YoeSksIGFsbF9vZihsdmwxX3gpLCBhbGxfb2YobHZsMl94KSwgYWxsX29mKGx2bDJfaWQpLCAKICAgICAgICAgICAgICAgICAgcG9wZGVucywgcmF0ZV9kYXksIGFsbF9vZih5KSkKICBkYXRhID0gZGF0YSAlPiUgCiAgICBkcGx5cjo6cmVuYW1lKHkgPSBhbGxfb2YoeSksCiAgICAgICAgICAgbHZsMV94ID0gYWxsX29mKGx2bDFfeCksCiAgICAgICAgICAgbHZsMl94ID0gYWxsX29mKGx2bDJfeCksCiAgICAgICAgICAgbHZsMl9pZCA9IGFsbF9vZihsdmwyX2lkKQogICAgICAgICAgICkKICAKICAjIGNvbmZpZ3VyZSBvcHRpbWl6YXRpb24gcHJvY2VkdXJlCiAgY3RybF9jb25maWcgPC0gbG1lQ29udHJvbChvcHQgPSAnb3B0aW0nLCBtYXhJdGVyID0gMTAwLCBtc01heEl0ZXIgPSAxMDApCgogICMgYmFzZWxpbmUKICBiYXNlbGluZSA8LSBsbWUoZml4ZWQgPSB5IH4gMSwgcmFuZG9tID0gfiAxIHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQoKICAjIHJhbmRvbSBpbnRlcmNlcHQgZml4ZWQgc2xvcGUKICByYW5kb21faW50ZXJjZXB0IDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gMSB8IGx2bDJfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyByYW5kb20gaW50ZXJjZXB0IHJhbmRvbSBzbG9wZQogIHJhbmRvbV9zbG9wZSA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICsgbHZsMl94LCAKICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCgogICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICBpbnRlcmFjdGlvbiA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94LCAKICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgIyBjcmVhdGUgbGlzdCB3aXRoIHJlc3VsdHMKICByZXN1bHRzIDwtIGxpc3QoJ2Jhc2VsaW5lJyA9IGJhc2VsaW5lLCAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9pbnRlcmNlcHQiID0gcmFuZG9tX2ludGVyY2VwdCwgCiAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGUiID0gcmFuZG9tX3Nsb3BlLAogICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb24iID0gaW50ZXJhY3Rpb24pCiAgCiAgCiAgaWYgKGN0cmxzID09ICdkZW0nIHwgY3RybHMgPT0gJ3ByZXYnKXsKICAgIAogICAgIyByYW5kb20gaW50ZXJjZXB0IHJhbmRvbSBzbG9wZQogICAgcmFuZG9tX3Nsb3BlX2N0cmxfZGVtIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3ggKyBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94ICsgcG9wZGVucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAgICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICAgIGludGVyYWN0aW9uX2N0cmxfaW50X2RlbSA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94ICsgbHZsMV94ICogcG9wZGVucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykgICAgICAgIAogICAgCiAgICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogICAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9pbnRlcmNlcHQiID0gcmFuZG9tX2ludGVyY2VwdCwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGVfY3RybF9kZW0iID0gcmFuZG9tX3Nsb3BlX2N0cmxfZGVtLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfaW50X2RlbSIgPSBpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0pCiAgfQogIAogIGlmIChjdHJscyA9PSAncHJldicpewogIAogICAgIyByYW5kb20gaW50ZXJjZXB0IHJhbmRvbSBzbG9wZQogICAgcmFuZG9tX3Nsb3BlX2N0cmxfcHJldiA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICsgbHZsMl94ICsgcG9wZGVucyArIHJhdGVfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCArIHJhdGVfZGF5IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpICAKICAgIAogICAgICAgICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICAgIGludGVyYWN0aW9uX2N0cmxfbWFpbl9wcmV2IDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBwb3BkZW5zICsgcmF0ZV9kYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgCiAgICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgICBpbnRlcmFjdGlvbl9jdHJsX2ludF9wcmV2PC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCArIGx2bDFfeCAqIHBvcGRlbnMgKyByYXRlX2RheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCArIHJhdGVfZGF5IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogICAgIyBjcmVhdGUgbGlzdCB3aXRoIHJlc3VsdHMKICAgIHJlc3VsdHMgPC0gbGlzdCgnYmFzZWxpbmUnID0gYmFzZWxpbmUsIAogICAgICAgICAgICAgICAgICAgICJyYW5kb21faW50ZXJjZXB0IiA9IHJhbmRvbV9pbnRlcmNlcHQsIAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGUiID0gcmFuZG9tX3Nsb3BlLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbiIgPSBpbnRlcmFjdGlvbiwKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2N0cmxfZGVtIiA9IHJhbmRvbV9zbG9wZV9jdHJsX2RlbSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSIgPSBpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0iID0gaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtLCAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZV9jdHJsX3ByZXYiID0gcmFuZG9tX3Nsb3BlX2N0cmxfcHJldiwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9tYWluX3ByZXYiID0gaW50ZXJhY3Rpb25fY3RybF9tYWluX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfaW50X3ByZXYiID0gaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldikKICB9CiAgCiAgaWYoY3RybHMgPT0gJ2V4cCcpewogICAgIyByYW5kb20gaW50ZXJjZXB0IHJhbmRvbSBzbG9wZQogIHJhbmRvbV9zbG9wZV9leHAgPC0gbG1lKGZpeGVkID0geSB+IChsdmwxX3ggKyBJKGx2bDFfeF4yKSkgKyBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiAobHZsMV94ICsgSShsdmwxX3heMikpIHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCgogICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICBpbnRlcmFjdGlvbl9leHAgPC0gbG1lKGZpeGVkID0geSB+IChsdmwxX3ggKyBJKGx2bDFfeF4yKSkgKiBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IChsdmwxX3ggKyBJKGx2bDFfeF4yKSkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpICAKICAKICAKICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogIHJlc3VsdHMgPC0gbGlzdCgnYmFzZWxpbmUnID0gYmFzZWxpbmUsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbiIgPSBpbnRlcmFjdGlvbiwgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZV9leHAiID0gcmFuZG9tX3Nsb3BlX2V4cCwKICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2V4cCIgPSBpbnRlcmFjdGlvbl9leHApCiAgfQogIAogIHJldHVybihyZXN1bHRzKQogICAgICAgIAp9CgojIGV4dHJhY3RzIHRhYmxlIHdpdGggY29lZmZpY2llbnRzIGFuZCB0ZXN0cyBzdGF0aXN0aWNzCmV4dHJhY3RfcmVzdWx0cyA8LSBmdW5jdGlvbihtb2RlbHMpIHsKICAKICBtb2RlbHNfc3VtbWFyeSA8LSBtb2RlbHMgJT4lIAogIG1hcChzdW1tYXJ5KSAlPiUgCiAgbWFwKCJ0VGFibGUiKSAlPiUgCiAgbWFwKGFzLmRhdGEuZnJhbWUpICU+JSAKICBtYXAocm91bmQsIDEwKSAKICAjICU+JSBtYXAofiAuW3N0cl9kZXRlY3Qocm93bmFtZXMoLiksICdJbnRlcnxsdmwnKSxdKQogIAogIHJldHVybihtb2RlbHNfc3VtbWFyeSkKICAKfQoKCmNvbXBhcmVfbW9kZWxzIDwtIGZ1bmN0aW9uKG1vZGVscykgewoKICBtZGxfbmFtZXMgPC0gbW9kZWxzICU+JSBuYW1lcygpCiAgCiAgc3RyID0gJycKICBmb3IgKGkgaW4gbWRsX25hbWVzKXsKICAgIAogICAgbWRsX3N0ciA8LSBwYXN0ZSgnbW9kZWxzJCcsIGksIHNlcCA9ICcnKQogICAgCiAgICBpZihpID09ICdiYXNlbGluZScpewogICAgICBzdHIgPC0gbWRsX3N0cgogICAgfWVsc2V7CiAgICBzdHIgPC0gcGFzdGUoc3RyLCBtZGxfc3RyLCBzZXA9JywgJykKICAgIH0KICB9CiAgCiAgYW5vdmFfc3RyIDwtIHBhc3RlMCgnYW5vdmEoJywgc3RyLCAnKScpCiAgbWRsX2NvbXAgPC0gZXZhbChwYXJzZSh0ZXh0PWFub3ZhX3N0cikpCiAgcm93bmFtZXMobWRsX2NvbXApID0gbWRsX25hbWVzCiAgcmV0dXJuKG1kbF9jb21wKQp9CgpgYGAKCiMjIFJlc2NhbGUgRGF0YQpgYGB7cn0KCmx2bDJfc2NhbGVkIDwtIGRmX3VzICU+JSAKICBzZWxlY3QoLXRpbWUsIC1kYXRlLCAtY291bnR5X25hbWUsIC1yYXRlX2RheSwKICAgICAgICAgLXNvY2Rpc3RfdGlsZXMsIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbiwgLWxvZXNzKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoLWNvdW50eV9maXBzKSwgc2NhbGUpCgpsdmwxX3NjYWxlZCA8LSBkZl91cyAlPiUgCiAgc2VsZWN0KGNvdW50eV9maXBzLCB0aW1lLCByYXRlX2RheSwgc29jZGlzdF9zaW5nbGVfdGlsZSwgc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lIAogIG11dGF0ZV9hdCh2YXJzKC1jb3VudHlfZmlwcywgLXRpbWUpLCBzY2FsZSkKCgpkZl91c19zY2FsZWQgPC0gcGx5cjo6am9pbihsdmwxX3NjYWxlZCwgbHZsMl9zY2FsZWQsIGJ5ID0gJ2NvdW50eV9maXBzJykgCmRmX3VzX3NjYWxlZF9wcmV2IDwtIGRmX3VzX3NjYWxlZCAlPiUgZmlsdGVyKHRpbWUgPiAyMCAmIHRpbWUgPD0gNTApCmRmX3VzX3NjYWxlZF9zb2NkaXN0IDwtIGRmX3VzX3NjYWxlZCAlPiUgZmlsdGVyKHRpbWUgPD0gMzApCgpgYGAKCgojIyBQcmVkaWN0IHByZXZhbGVuY2UKIyMjIHByZXZhbGVuY2UgfiBvcGVubmVzcwpgYGB7cn0KCm1vZGVsc19vX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX28nLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19vX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fY292aWQpCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9Cgptb2RlbHNfY19jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfcHJldiwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2NfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfY19jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2VfY292aWQgPC1ydW5fbW9kZWxzKHkgPSAncmF0ZV9kYXknLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2VfY292aWQpCgoKYGBgCgojIyMgcHJldmFsZW5jZSB+IGFncmVlYWJsZW5lc3MKYGBge3J9Cgptb2RlbHNfYV9jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2EnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfcHJldiwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2FfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfYV9jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gbmV1cm90aWNpc20KYGBge3J9Cgptb2RlbHNfbl9jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfcHJldiwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX25fY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfbl9jb3ZpZCkKCgpgYGAKCgojIyBQcmVkaWN0IHNvY2lhbCBkaXN0YW5jaW5nCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IG9wZW5uZXNzCmBgYHtyfQoKbW9kZWxzX29fc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX28nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ3ByZXYnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19vX3NkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fc2QpCgoKYGBgCgojIyMgc29jaWFsIGRpc3RhbmNpbmcgfiBjb25zY2llbnRpb3VzbmVzcwpgYGB7cn0KCm1vZGVsc19jX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19jJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3NvY2Rpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfY19zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19jX3NkKQoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2Vfc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2UnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ3ByZXYnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX3NkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2Vfc2QpCgoKYGBgCgojIyMgc29jaWFsIGRpc3RhbmNpbmcgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKbW9kZWxzX2Ffc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2EnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ3ByZXYnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19hX3NkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2Ffc2QpCgoKYGBgCgojIyMgc29jaWFsIGRpc3RhbmNpbmcgfiBuZXVyb3RpY2lzbQpgYGB7cn0KCm1vZGVsc19uX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19uJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3NvY2Rpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfbl9zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19uX3NkKQoKYGBgCgoKIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlIAoKIyMjIERlZmluZSBmdW5jdGlvbiB0byBjcmVhdGUgb3ZlcnZpZXcgdGFibGVzCmBgYHtyfQoKc3VtbWFyeV90YWJsZSA8LSBmdW5jdGlvbihtb2RlbHMsIGR2X25hbWUsIHByZXY9Ril7CgogIHRlbXBfZGZfY3RybF9tYWluIDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50IDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gTlVMTAogIAogIGZvciAoaSBpbiBtb2RlbHMpewogICAgcmVzdWx0cyA8LSBpICU+JSBleHRyYWN0X3Jlc3VsdHMoKQogICAgCiAgICByZXN1bHRzX2N0cmxfbWFpbiA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW1bJ2x2bDFfeDpsdmwyX3gnLF0KICAgIHRlbXBfZGZfY3RybF9tYWluIDwtIHRlbXBfZGZfY3RybF9tYWluICU+JSByYmluZChyZXN1bHRzX2N0cmxfbWFpbikKICAgIAogICAgcmVzdWx0c19jdHJsX2ludCA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfaW50X2RlbVsnbHZsMV94Omx2bDJfeCcsXQogICAgdGVtcF9kZl9jdHJsX2ludCA8LSB0ZW1wX2RmX2N0cmxfaW50ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50KQogICAgCiAgICBpZihwcmV2KXsKICAgICAgcmVzdWx0c19jdHJsX2ludF9wcmV2IDwtIHJlc3VsdHMkaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldlsnbHZsMV94Omx2bDJfeCcsXQogICAgICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gdGVtcF9kZl9jdHJsX2ludF9wcmV2ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50X3ByZXYpCiAgICB9CiAgICAgICAgCiAgfQogIAogIG5hbWVzX2N0cmxfbWFpbiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9tYWluKSA8LSBuYW1lc19jdHJsX21haW4KCiAgbmFtZXNfY3RybF9pbnQgPC0gcGFzdGUwKGR2X25hbWUsICd+JywgYygnbycsICdjJywgJ2UnLCAnYScsICduJyksICcqdGltZScsICdfY3J0bF9wb3BkZW5zKnRpbWUnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnQpIDwtIG5hbWVzX2N0cmxfaW50CgogIGlmKHByZXYpewogICAgbmFtZXNfY3RybF9pbnRfcHJldiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMqdGltZV9wcmV2JykKICAgIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnRfcHJldikgPC0gbmFtZXNfY3RybF9pbnRfcHJldgogICAgCiAgICBzdW1fdGFiIDwtIHJiaW5kKHRlbXBfZGZfY3RybF9tYWluLCB0ZW1wX2RmX2N0cmxfaW50LCB0ZW1wX2RmX2N0cmxfaW50X3ByZXYpICU+JSByb3VuZCg0KQogIH1lbHNlewogICAgc3VtX3RhYiA8LSByYmluZCh0ZW1wX2RmX2N0cmxfbWFpbiwgdGVtcF9kZl9jdHJsX2ludCkgJT4lIHJvdW5kKDQpCiAgfQoKCiAgCiAgcmV0dXJuKHN1bV90YWIpCgp9IAoKYGBgCgojIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlcwpgYGB7cn0KIyBwcmV2YWxlbmNlCm1vZGVsc19wcmV2IDwtIGxpc3QobW9kZWxzX29fY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX2NvdmlkLCAKICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9jb3ZpZCwgCiAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2FfY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX2NvdmlkKQoKc3VtX3RhYl9wcmV2IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3ByZXYsIGR2X25hbWUgPSAncHJldicpCgp3cml0ZS50YWJsZShzdW1fdGFiX3ByZXYsIHF1b3RlPUYpCgojIHNvY2lhbCBkaXN0YW5jaW5nCm1vZGVsc19zb2NkaXN0IDwtIGxpc3QobW9kZWxzX29fc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX3NkLCAKICAgICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9zZCwgCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2Ffc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX3NkKQoKc3VtX3RhYl9zb2NkaXN0IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3NvY2Rpc3QsIGR2X25hbWUgPSAnc29jZGlzdCcsIHByZXY9VCkKCndyaXRlLnRhYmxlKHN1bV90YWJfc29jZGlzdCwgcXVvdGU9RikKCnN1bV90YWJfc29jZGlzdAoKYGBgCgoKCgojIENvbmRpdGlvbmFsIHJhbmRvbSBmb3Jlc3QgYW5hbHlzaXMgCgojIyMgRXh0cmFjdCBzbG9wZXMKYGBge3J9CgojIHNsb3BlIHByZXZhbGVuY2UKZGZfdXNfc2xvcGVfcHJldiA8LSBkZl91c19zY2FsZWRfcHJldiAlPiUgc3BsaXQoLiRjb3VudHkpICU+JSAKICBtYXAofiBsbShyYXRlX2RheSB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKGNvZWYpICU+JSAKICBtYXBfZGJsKCd0aW1lJykgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpICU+JSAKICByZW5hbWUoc2xvcGVfcHJldiA9ICcuJykKCmRmX3VzX3Nsb3BlX3ByZXYgPC0gZGZfdXNfc2NhbGVkX3ByZXYgJT4lIAogIHNlbGVjdCgtdGltZSwgLXJhdGVfZGF5LCAtc29jZGlzdF9zaW5nbGVfdGlsZSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZShjb3VudHlfZmlwcyA9IGFzLmNoYXJhY3Rlcihjb3VudHlfZmlwcykpICU+JQogIGlubmVyX2pvaW4oZGZfdXNfc2xvcGVfcHJldiwgYnkgPSAnY291bnR5X2ZpcHMnKSAlPiUKICBkcm9wX25hKCkKCgojIHNsb3BlIHNvY2lhbCBkaXN0YW5jaW5nCmRmX3VzX3Nsb3BlX3NvY2Rpc3QgPC0gZGZfdXNfc2NhbGVkX3NvY2Rpc3QgJT4lIHNwbGl0KC4kY291bnR5KSAlPiUgCiAgbWFwKH4gbG0oc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbiB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKGNvZWYpICU+JSAKICBtYXBfZGJsKCd0aW1lJykgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpICU+JSAKICByZW5hbWUoc2xvcGVfc29jZGlzdCA9ICcuJykKCmRmX3VzX3Nsb3BlX3NvY2Rpc3QgPC0gZGZfdXNfc2NhbGVkX3NvY2Rpc3QgJT4lIAogIHNlbGVjdCgtdGltZSwgLXJhdGVfZGF5LCAtc29jZGlzdF9zaW5nbGVfdGlsZSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZShjb3VudHlfZmlwcyA9IGFzLmNoYXJhY3Rlcihjb3VudHlfZmlwcykpICU+JQogIGlubmVyX2pvaW4oZGZfdXNfc2xvcGVfc29jZGlzdCwgYnkgPSAnY291bnR5X2ZpcHMnKSAlPiUKICBkcm9wX25hKCkKCmBgYAoKIyMjIEV4cGxvcmUgZGlzdHJpYnV0aW9uIG9mIHNsb3BlcwpgYGB7cn0KZGZfdXNfc2xvcGVfcHJldiAlPiUgZ2dwbG90KGFlcyhzbG9wZV9wcmV2KSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwKQoKZGZfdXNfc2xvcGVfc29jZGlzdCAlPiUgZ2dwbG90KGFlcyhzbG9wZV9zb2NkaXN0KSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwKQoKYGBgCgojIENSRiBwcmV2YWxlbmNlIAojIyMgQ1JGIHByZXZhbGVuY2UgfiBvcGVubmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfb19maXRfcHJldiA8LSBjZm9yZXN0KHNsb3BlX3ByZXYgfiBwZXJzX28gKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9wcmV2Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX29fdmFyaW1wX3ByZXYgPC0gdmFyaW1wKGNyZl9vX2ZpdF9wcmV2LCBucGVybSA9IDEpCmNyZl9vX3ZhcmltcF9jb25kX3ByZXYgPC0gdmFyaW1wKGNyZl9vX2ZpdF9wcmV2LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9vX3ZhcmltcF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9vX3ZhcmltcF9jb25kX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMjIyBDUkYgcHJldmFsZW5jZSB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9jX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfYyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfY192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2NfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIyMgQ1JGIHByZXZhbGVuY2UgfiBleHRyYXZlcnNpb24KYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2VfZml0X3ByZXYgPC0gY2ZvcmVzdChzbG9wZV9wcmV2IH4gcGVyc19lICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfcHJldlstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9lX3ZhcmltcF9wcmV2IDwtIHZhcmltcChjcmZfZV9maXRfcHJldiwgbnBlcm0gPSAxKQpjcmZfZV92YXJpbXBfY29uZF9wcmV2IDwtIHZhcmltcChjcmZfZV9maXRfcHJldiwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfZV92YXJpbXBfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfZV92YXJpbXBfY29uZF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKCiMjIyBDUkYgcHJldmFsZW5jZSB+IGFncmVlYWJsZW5lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2FfZml0X3ByZXYgPC0gY2ZvcmVzdChzbG9wZV9wcmV2IH4gcGVyc19hICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfcHJldlstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9hX3ZhcmltcF9wcmV2IDwtIHZhcmltcChjcmZfYV9maXRfcHJldiwgbnBlcm0gPSAxKQpjcmZfYV92YXJpbXBfY29uZF9wcmV2IDwtIHZhcmltcChjcmZfYV9maXRfcHJldiwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfYV92YXJpbXBfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfYV92YXJpbXBfY29uZF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKCiMjIyBDUkYgcHJldmFsZW5jZSB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMjIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBvcGVubmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfb19maXRfc29jZGlzdCA8LSBjZm9yZXN0KHNsb3BlX3NvY2Rpc3QgfiBwZXJzX28gKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX29fdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9vX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9vX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9vX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9vX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9vX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgojIyMgQ1JGIHNvY2lhbCBkaXN0YW5jaW5nIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2NfZml0X3NvY2Rpc3QgPC0gY2ZvcmVzdChzbG9wZV9zb2NkaXN0IH4gcGVyc19jICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9jX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfY192YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyMjIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfZV9maXRfc29jZGlzdCA8LSBjZm9yZXN0KHNsb3BlX3NvY2Rpc3QgfiBwZXJzX2UgKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2VfdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9lX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9lX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9lX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9lX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9lX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgojIyMgQ1JGIHNvY2lhbCBkaXN0YW5jaW5nIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfYV9maXRfc29jZGlzdCA8LSBjZm9yZXN0KHNsb3BlX3NvY2Rpc3QgfiBwZXJzX2EgKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2FfdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9hX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9hX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9hX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9hX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9hX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgoKIyMjIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMgUHJlZGljdCBzbG9wZXMgd2l0aCBsaW5lYXIgbW9kZWxzCiMjIyBMaW5lYXIgbW9kZWxzIHByZWRpY3Rpbmcgc2xvcGVzIGZyb20gcGVyc29uYWxpdHkKYGBge3J9CgpsbV9zbG9wZV9wcmV2X3BlcnMgPC0gbG0oc2xvcGVfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2xvcGVfcHJldikKbG1fc2xvcGVfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCgpsbV9zbG9wZV9zb2NkaXN0X3BlcnMgPC0gbG0oc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2xvcGVfc29jZGlzdCkKbG1fc2xvcGVfc29jZGlzdF9wZXJzICU+JSBzdW1tYXJ5KCkKCmBgYAoKIyMjIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBzbG9wZXMgd2l0aCBjb250cm9scwpgYGB7cn0KCmxtX3Nsb3BlX3ByZXZfcGVycyA8LSBsbShzbG9wZV9wcmV2IH4gcGVyc19vICsgcGVyc19jICsgcGVyc19lICsgcGVyc19hICsgcGVyc19uICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFudWZhY3QgKyB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3Nsb3BlX3ByZXYpCmxtX3Nsb3BlX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fc2xvcGVfc29jZGlzdF9wZXJzIDwtIGxtKHNsb3BlX3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24gKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKyBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW51ZmFjdCArIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2xvcGVfc29jZGlzdCkKbG1fc2xvcGVfc29jZGlzdF9wZXJzICU+JSBzdW1tYXJ5KCkKCmBgYAoKCgojIENoYW5nZSBwb2ludCBhbmFseXNpcwojIyMgUHJlcGFyYXRpb24KYGBge3J9CgojIGtlZXAgb25seSBjb3VudGllcyB3aXRoIGZ1bGwgZGF0YQpmaXBzX2NvbXBsZXRlIDwtIGRmX3VzX3NjYWxlZCAlPiUgCiAgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBzdW1tYXJpemUobiA9IG4oKSkgJT4lIAogIGZpbHRlcihuPT1tYXgoLiRuKSkgJT4lIAogIC4kY291bnR5X2ZpcHMKYGBgCgojIyMgUHJldmFsZW5jZQpgYGB7cn0KCiMgcnVuIGNoYW5nZXBvaW50IGFuYWx5c2lzCmRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgPC0gZGZfdXNfc2NhbGVkICU+JSBzZWxlY3QoY291bnR5X2ZpcHMsIHJhdGVfZGF5KSAlPiUKICBmaWx0ZXIoY291bnR5X2ZpcHMgJWluJSBmaXBzX2NvbXBsZXRlKSAlPiUgCiAgc3BsaXQoLiRjb3VudHlfZmlwcykgJT4lCiAgbWFwKH4gY3B0Lm1lYW52YXIoYXMudmVjdG9yKC4kcmF0ZV9kYXkpLAogICAgICAgICAgICAgICAgICAgIGNsYXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgcGFyYW0uZXN0aW1hdGVzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgUT0xKSkKCiMgY2FsY3VsYXRlIGNoYW5nZSBwb2ludApkZl91c19wcmV2X2NwdF9kYXkgPC0gZGZfdXNfcHJldl9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKGNwdHMpICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUoY3B0X2RheV9wcmV2ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIG1lYW4gZGlmZmVyZW5jZXMKZGZfdXNfcHJldl9jcHRfbWVhbl9kaWZmIDwtIGRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJG1lYW4pICU+JSAKICBtYXAofiAuWzJdLS5bMV0pICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUobWVhbl9kaWZmX3ByZXYgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBjYWxjdWxhdGUgdmFyYWluY2UgZGlmZmVyZW5jZXMKZGZfdXNfcHJldl9jcHRfdmFyX2RpZmYgPC0gZGZfdXNfcHJldl9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKHBhcmFtLmVzdCkgJT4lIAogIG1hcCh+IC4kdmFyaWFuY2UpICU+JSAKICBtYXAofiAuWzJdLS5bMV0pICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUodmFyX2RpZmZfcHJldiA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIG1lcmdlIG5ldyB2YXJpYWJsZXMgCmRmX3VzX2NwdF9wcmV2IDwtIGRmX3VzX3NjYWxlZCAlPiUKICBzZWxlY3QoLXRpbWUsIC1yYXRlX2RheSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGUsIC1zb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZShjb3VudHlfZmlwcyA9IGFzLmNoYXJhY3Rlcihjb3VudHlfZmlwcykpICU+JQogIGxlZnRfam9pbihkZl91c19wcmV2X2NwdF9kYXksIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19wcmV2X2NwdF9tZWFuX2RpZmYsIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19wcmV2X2NwdF92YXJfZGlmZiwgYnk9J2NvdW50eV9maXBzJykKCmRmX3VzX2NwdF9wcmV2ICU+JSBzZWxlY3QoY3B0X2RheV9wcmV2KSAlPiUgbWFwKGhpc3QpCmRmX3VzX2NwdF9wcmV2ICU+JSBzZWxlY3QobWVhbl9kaWZmX3ByZXYpICU+JSBtYXAoaGlzdCkKZGZfdXNfY3B0X3ByZXYgJT4lIHNlbGVjdCh2YXJfZGlmZl9wcmV2KSAlPiUgbWFwKGhpc3QpCgpkZl91c19jcHRfcHJldiAlPiUgZGltKCkKZGZfdXNfY3B0X3ByZXYgJT4lIGRyb3BfbmEoKSAlPiUgZGltKCkKCmBgYAoKCmBgYHtyfQoKZm9yKGkgaW4gaGVhZChkZl91c19wcmV2X2NwdF9yZXN1bHRzLDUpKXsKICBwbG90KGkpCn0KCmBgYAoKIyMjIFNvY2lhbCBkaXN0YW5jaW5nCmBgYHtyfQoKIyBydW4gY2hhbmdlcG9pbnQgYW5hbHlzaXMKZGZfdXNfc29jZGlzdF9jcHRfcmVzdWx0cyA8LSBkZl91c19zY2FsZWQgJT4lIHNlbGVjdChjb3VudHlfZmlwcywgc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lCiAgZmlsdGVyKGNvdW50eV9maXBzICVpbiUgZmlwc19jb21wbGV0ZSkgJT4lIAogIHNwbGl0KC4kY291bnR5X2ZpcHMpICU+JQogIG1hcCh+IGNwdC5tZWFudmFyKGFzLnZlY3RvciguJHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pLAogICAgICAgICAgICAgICAgICAgICNwZW5hbHR5ID0gJ0FzeW1wdG90aWMnLAogICAgICAgICAgICAgICAgICAgIGNsYXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgcGFyYW0uZXN0aW1hdGVzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgUT0xLAogICAgICAgICAgICAgICAgICAgIHRlc3Quc3RhdCA9ICdOb3JtYWwnKSkKCiMgY2FsY3VsYXRlIGNoYW5nZSBwb2ludApkZl91c19zb2NkaXN0X2NwdF9kYXkgPC0gZGZfdXNfc29jZGlzdF9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKGNwdHMpICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUoY3B0X2RheV9zb2NkaXN0ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIG1lYW4gZGlmZmVyZW5jZXMKZGZfdXNfc29jZGlzdF9jcHRfbWVhbl9kaWZmIDwtIGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJG1lYW4pICU+JSAKICBtYXAofiAuWzJdLS5bMV0pICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUobWVhbl9kaWZmX3NvY2Rpc3QgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBjYWxjdWxhdGUgdmFyYWluY2UgZGlmZmVyZW5jZXMKZGZfdXNfc29jZGlzdF9jcHRfdmFyX2RpZmYgPC0gZGZfdXNfc29jZGlzdF9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKHBhcmFtLmVzdCkgJT4lIAogIG1hcCh+IC4kdmFyaWFuY2UpICU+JSAKICBtYXAofiAuWzJdLS5bMV0pICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUodmFyX2RpZmZfc29jZGlzdCA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIG1lcmdlIG5ldyB2YXJpYWJsZXMgCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgPC0gZGZfdXNfY3B0X3ByZXYgJT4lCiAgbGVmdF9qb2luKGRmX3VzX3NvY2Rpc3RfY3B0X2RheSwgYnk9J2NvdW50eV9maXBzJykgJT4lCiAgbGVmdF9qb2luKGRmX3VzX3NvY2Rpc3RfY3B0X21lYW5fZGlmZiwgYnk9J2NvdW50eV9maXBzJykgJT4lCiAgbGVmdF9qb2luKGRmX3VzX3NvY2Rpc3RfY3B0X3Zhcl9kaWZmLCBieT0nY291bnR5X2ZpcHMnKQoKZGZfdXNfY3B0X3ByZXZfc29jZGlzdCAlPiUgc2VsZWN0KGNwdF9kYXlfc29jZGlzdCkgJT4lIG1hcChoaXN0KQpkZl91c19jcHRfcHJldl9zb2NkaXN0ICU+JSBzZWxlY3QobWVhbl9kaWZmX3NvY2Rpc3QpICU+JSBtYXAoaGlzdCkKZGZfdXNfY3B0X3ByZXZfc29jZGlzdCAlPiUgc2VsZWN0KHZhcl9kaWZmX3NvY2Rpc3QpICU+JSBtYXAoaGlzdCkKCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIGRpbSgpCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIGRyb3BfbmEoKSAlPiUgZGltKCkKCmBgYAoKYGBge3J9Cgpmb3IoaSBpbiBoZWFkKGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMsNSkpewogIHBsb3QoaSkKfQoKYGBgCgojIFByZWRpY3RpbmcgY2hhbmdlIHBvaW50cyAKIyMjIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBjaGFuZ2UgcG9pbnRzIChubyBjb250cm9scykKYGBge3J9CgpsbV9jcHJfcHJldl9wZXJzIDwtIGxtKGNwdF9kYXlfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfY3B0X3ByZXZfc29jZGlzdCkKbG1fY3ByX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fY3B0X3NvY2Rpc3RfcGVycyA8LSBsbShjcHRfZGF5X3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgojIyMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIGNoYW5nZSBwb2ludHMgd2l0aCBjb250cm9scwpgYGB7cn0KCmxtX2NwdF9wcmV2X3BlcnMgPC0gbG0oY3B0X2RheV9wcmV2IH4gcGVyc19vICsgcGVyc19jICsgcGVyc19lICsgcGVyc19hICsgcGVyc19uICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFudWZhY3QgKyB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9wcmV2X3BlcnMgJT4lIHN1bW1hcnkoKQoKbG1fY3B0X3NvY2Rpc3RfcGVycyA8LSBsbShjcHRfZGF5X3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24gKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKyBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW51ZmFjdCArIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfY3B0X3ByZXZfc29jZGlzdCkKbG1fY3B0X3NvY2Rpc3RfcGVycyAlPiUgc3VtbWFyeSgpCgpgYGAKCiMjIEV4cGxvcmUgcXVhZHJhdGljIHRyZW5kcyAKCiMjIyBwcmV2YWxlbmNlIH4gb3Blbm5lc3MKYGBge3J9Cgptb2RlbHNfb19jb3ZpZF9leHAgPC1ydW5fbW9kZWxzKHkgPSAncmF0ZV9kYXknLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfbycsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfcHJldiwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2V4cCcpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX29fY292aWRfZXhwKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fY292aWRfZXhwKQoKYGBgCgoKIyMjIHByZXZhbGVuY2UgfiBjb25zY2llbnRpb3VzbmVzcwpgYGB7cn0KCm1vZGVsc19jX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZF9wcmV2LAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZXhwJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfY19jb3ZpZF9leHApCgpjb21wYXJlX21vZGVscyhtb2RlbHNfY19jb3ZpZF9leHApCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2VfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKbW9kZWxzX2FfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfYScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19hX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19hX2NvdmlkX2V4cCkKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBuZXVyb3RpY2lzbQpgYGB7cn0KCm1vZGVsc19uX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZF9wcmV2LAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZXhwJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfbl9jb3ZpZF9leHApCgpjb21wYXJlX21vZGVscyhtb2RlbHNfbl9jb3ZpZF9leHApCgpgYGAKCiMjIyBzb2NkaXN0IH4gb3Blbm5lc3MKYGBge3J9Cgptb2RlbHNfb19jb3ZpZF9leHAgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbicsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19vJywKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZF9zb2NkaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZXhwJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfb19jb3ZpZF9leHApCgpjb21wYXJlX21vZGVscyhtb2RlbHNfb19jb3ZpZF9leHApCgpgYGAKCgojIyMgc29jZGlzdCB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKbW9kZWxzX2NfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19jJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2V4cCcpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2NfY292aWRfZXhwKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2NfY292aWRfZXhwKQoKYGBgCgojIyMgc29jZGlzdCB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCm1vZGVsc19lX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkX3NvY2Rpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmBgYAoKIyMjIHNvY2Rpc3QgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKbW9kZWxzX2FfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19hJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2V4cCcpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2FfY292aWRfZXhwKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2FfY292aWRfZXhwKQoKYGBgCgojIyMgc29jZGlzdCB+IG5ldXJvdGljaXNtCmBgYHtyfQoKbW9kZWxzX25fY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19uJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWRfc29jZGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2V4cCcpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX25fY292aWRfZXhwKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX25fY292aWRfZXhwKQoKYGBgCgo=